﻿
Public Module share
    Public Function debug_mode() As Boolean
#If DEBUG Then
        Return True
#Else
        Return False
#End If
    End Function

    Public Function assert(ByVal v As Boolean,
                           ByVal ParamArray msg() As String) As Boolean
        Return assert(v, String.Concat(msg))
    End Function

    Public Function assert(ByVal v As Boolean,
                           Optional ByVal msg As String = Nothing) As Boolean
        If Not v Then
            If debug_mode() Then
                If Debugger.IsAttached() Then
                    Debugger.Break()
                Else
                    Debugger.Launch()
                End If
            Else
                Dim m As String = Nothing
                m = "assert failed"
                If Not String.IsNullOrEmpty(msg) Then
                    m = String.Concat(m, ", msg ", msg)
                End If
                Environment.FailFast(m)
            End If
        End If

        Return v
    End Function

    Public Function compare(Of T1, T2)(ByVal i As T1, ByVal j As T2) As Int32
        If i Is Nothing AndAlso j Is Nothing Then
            Return 0
        ElseIf i Is Nothing Then
            Return -1
        ElseIf j Is Nothing Then
            Return 1
        Else
            If i.istype(Of IComparable(Of T2))() Then
                Return -_compare(j, i.as(Of IComparable(Of T2)))
            ElseIf j.istype(Of IComparable(Of T1))() Then
                Return _compare(i, j.as(Of IComparable(Of T1)))
            ElseIf i.istype(Of IComparable)() Then
                Return _compare(i.as(Of IComparable)(), j)
            ElseIf j.istype(Of IComparable)() Then
                Return -_compare(j.as(Of IComparable)(), i)
            Else
                assert(False, "cannot compare ", i.GetType().FullName(), " with ", j.GetType().FullName())
                Return 0
            End If
        End If
    End Function

    Private Function _compare(Of T1, T2 As IComparable(Of T1))(ByVal i As T1, ByVal j As T2) As Int32
        assert(Not i Is Nothing)
        assert(Not j Is Nothing)
        Return -j.CompareTo(i)
    End Function

    Private Function _compare(Of T As IComparable)(ByVal i As T, ByVal j As Object) As Int32
        assert(Not i Is Nothing)
        assert(Not j Is Nothing)
        Return i.CompareTo(j)
    End Function
End Module
